package com.punch.course.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.punch.common.enums.course.ClassAuditEnum;
import com.punch.common.enums.course.GradeEnum;
import com.punch.common.exception.BusinessException;
import com.punch.common.feign.FeignStudentService;
import com.punch.common.page.PageInfo;
import com.punch.common.redis.utils.UserUtil;
import com.punch.common.vo.course.SignInClassVO;
import com.punch.common.vo.course.SignInStudentVO;
import com.punch.common.vo.user.student.StudentPageVO;
import com.punch.course.exception.CourseExceptionEnum;
import com.punch.course.mapper.ClassMapper;
import com.punch.course.model.ClassSchedule;
import com.punch.course.model.PunchClass;
import com.punch.course.model.StudentCourseSchedule;
import com.punch.course.service.ClassScheduleService;
import com.punch.course.service.SignInService;
import com.punch.course.service.StudentCourseScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 签到实现层
 */
@Service
@Slf4j
public class SignInServiceImpl implements SignInService {

    @Resource
    private ClassMapper classMapper;

    @Resource
    private ClassScheduleService classScheduleService;

    @Resource
    private StudentCourseScheduleService studentCourseScheduleService;

    @Resource
    private FeignStudentService feignStudentService;

    /**
     * 查找当前登录教师的需要上课的课程列表
     *
     * @return PageInfo
     */
    @Override
    public List<SignInClassVO> listClassCourse() {
        Long loginUserId = UserUtil.getLoginUserId();
        QueryWrapper<PunchClass> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PunchClass::getTeacherId, loginUserId).eq(PunchClass::getClassState, ClassAuditEnum.BEGIN_CLASS.getCode());
        List<PunchClass> classList = classMapper.selectList(queryWrapper);
        List<SignInClassVO> list = new ArrayList<>();
        if (CollUtil.isEmpty(classList)) {
            return list;
        }
        List<Long> classIds = new ArrayList<>();
        classList.forEach(punchClass -> classIds.add(punchClass.getId()));
        List<ClassSchedule> classSchedules = classScheduleService.listByClassIds(classIds);
        classList.forEach(punchClass -> classSchedules.stream().filter(u -> u.getClassId().equals(punchClass.getId())).findAny().ifPresent(u -> {
            SignInClassVO signInClassVO = new SignInClassVO();
            signInClassVO.setClassName(punchClass.getClassName());
            signInClassVO.setCourseName(punchClass.getCourseName());
            LocalDateTime courseStartDate = u.getCourseStartDate();
            StringBuilder classTime = new StringBuilder();
            classTime.append(courseStartDate.toLocalDate())
                    .append(" ")
                    .append(courseStartDate.toLocalTime())
                    .append("~")
                    .append(u.getCourseEndDate().toLocalTime());
            signInClassVO.setClassTime(classTime.toString());
            signInClassVO.setClassPlace(punchClass.getCreateName() + " " + punchClass.getClassRoomName());
            signInClassVO.setSignUpNumber(punchClass.getSignUpNumber());
            signInClassVO.setSchoolId(punchClass.getCreateId());
            signInClassVO.setClassId(punchClass.getId());
            list.add(signInClassVO);
        }));
        return list;
    }

    /**
     * 获取课程下学生列表
     *
     * @param classId     学生id
     * @param studentName 学姓名
     * @param schoolId    学校id
     * @param currPage    当前页
     * @param pageSize    每页大小
     * @return List<SignInStudentVO>
     */
    @Override
    public PageInfo<SignInStudentVO> listCourseStudent(Long classId, String studentName, Long schoolId, Integer currPage, Integer pageSize) {
        if (StrUtil.isEmpty(studentName)) {
            return courseClassStudent(classId, currPage, pageSize);
        } else {
            return searchCourseStudent(schoolId, studentName, classId, currPage, pageSize);
        }
    }

    /**
     * 修改学生课表签到状态
     *
     * @param courseScheduleId 签到id
     * @param signInStatus     签到状态 0-还原初始状态(清空) 1-已到 2-请假
     * @return long
     */
    @Override
    public Long changeSignInStatus(Long courseScheduleId, Integer signInStatus) {
        //当前时间超过17:00点不让操作
        LocalTime localTime = LocalTime.now();
        if (localTime.getHour() >= 17) {
            throw new BusinessException(CourseExceptionEnum.SIGN_IN_EXCEED_TIME);
        }
        StudentCourseSchedule studentCourseSchedule = new StudentCourseSchedule();
        studentCourseSchedule.setId(courseScheduleId);
        studentCourseSchedule.setStatus(signInStatus);
        studentCourseScheduleService.updateById(studentCourseSchedule);
        return courseScheduleId;
    }

    /**
     * 统计签到人数
     *
     * @param classId 班级课程id
     * @return Integer
     */
    @Override
    public Integer getSignInCount(Long classId) {
        LocalDate localDate = LocalDate.now();
        QueryWrapper<StudentCourseSchedule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StudentCourseSchedule::getClassId, classId)
                .eq(StudentCourseSchedule::getClassDate, localDate)
                .eq(StudentCourseSchedule::getStatus, 1);
        return studentCourseScheduleService.count(queryWrapper);
    }


    /**
     * 课程班级学生列表
     *
     * @param classId  课程id
     * @param currPage 当前页
     * @param pageSize 每页大小
     * @return
     */
    private PageInfo<SignInStudentVO> courseClassStudent(Long classId, Integer currPage, Integer pageSize) {
        PageInfo<SignInStudentVO> pageInfo = new PageInfo<>(currPage, pageSize);
        List<SignInStudentVO> retList = new ArrayList<>();
        LocalDate localDate = LocalDate.now();
        QueryWrapper<StudentCourseSchedule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StudentCourseSchedule::getClassId, classId)
                .eq(StudentCourseSchedule::getClassDate, localDate);
        int count = studentCourseScheduleService.count(queryWrapper);
        int start = (currPage - 1) * pageSize;
        queryWrapper.lambda().last("limit " + start + "," + pageSize);
        List<StudentCourseSchedule> list = studentCourseScheduleService.list(queryWrapper);
        list.forEach(u -> {
            SignInStudentVO signInStudentVO = new SignInStudentVO();
            signInStudentVO.setCourseScheduleId(u.getId());
            signInStudentVO.setStudentName(u.getStudentName());
            signInStudentVO.setSex(u.getStudentSex());
            signInStudentVO.setGradeClass(u.getStudentGrade() + " " + u.getStudentClass());
            signInStudentVO.setSignInStatus(u.getStatus());
//            signInStudentVO.setCourseName(u.getCourseName());
            retList.add(signInStudentVO);
        });
        pageInfo.setData(retList);
        pageInfo.setTotalCount(count);
        return pageInfo;
    }

    /**
     * 搜索学生
     *
     * @param schoolId    学校id
     * @param studentName 学生姓名
     * @param classId     课程班级id
     * @param currPage    当前页
     * @param pageSize    每页大小
     * @return List<SignInStudentVO>
     */
    private PageInfo<SignInStudentVO> searchCourseStudent(Long schoolId, String studentName, Long classId, Integer currPage, Integer pageSize) {
        long start = System.currentTimeMillis();
        PageInfo<SignInStudentVO> pageInfo = new PageInfo<>(currPage, pageSize);
        PageInfo<StudentPageVO> stuPage = feignStudentService.feignStudentList(schoolId, studentName, currPage, pageSize);
        if (stuPage.getTotalCount() == 0) {
            return pageInfo;
        }
        List<SignInStudentVO> retList = new ArrayList<>(10);
        LocalDate now = LocalDate.now();
        List<Long> stuIdList = new ArrayList<>(10);
        stuPage.getData().forEach(stu -> {
            stuIdList.add(stu.getStudentId());
        });
        //查找当天学生id参加课程列表
        List<StudentCourseSchedule> stuCourseList = studentCourseScheduleService.listStuByStuIds(schoolId, stuIdList, now);
        StringBuilder sb = new StringBuilder();
        stuPage.getData().forEach(stu -> {
            SignInStudentVO signInStudentVO = new SignInStudentVO();
            signInStudentVO.setStudentName(stu.getName());
            signInStudentVO.setSex(stu.getSex());
            signInStudentVO.setGradeClass(GradeEnum.getName(stu.getGradeYear()) + " " + stu.getGradeClass());
            List<StudentCourseSchedule> signUpStuList = stuCourseList.stream().filter(u -> u.getStudentId().equals(stu.getStudentId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(signUpStuList)) {
                signUpStuList.forEach(u -> {
                    sb.append(u.getCourseName()).append(";");
                    if (u.getClassId().equals(classId)) {
                        signInStudentVO.setCourseScheduleId(u.getId());
                    }
                });
                sb.deleteCharAt(sb.length() - 1);
                signInStudentVO.setCourseName(sb.toString());
                sb.delete(0, sb.length());

            }
            retList.add(signInStudentVO);
        });
        pageInfo.setData(retList);
        pageInfo.setTotalCount(stuPage.getTotalCount());
        log.info("接口查询分页时间:{}", System.currentTimeMillis() - start);
        return pageInfo;
    }


}
